package com.xdf.ecommerce.config;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import reactor.core.publisher.Mono;
import java.util.List;

/**
 * @author chanchaw
 * @create 2025-10-17 19:39
 */
@RequiredArgsConstructor
@Slf4j
@Service
public class DynamicRouteServiceImpl implements ApplicationEventPublisherAware {
    private final RouteDefinitionWriter routeDefinitionWriter;
    private final RouteDefinitionLocator routeDefinitionLocator;
    private final ApplicationEventPublisher publisher;
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {

    }

    public String addRouteDefinition(RouteDefinition definition){
        String ret = "网关新增路由：" + definition.toString();
        log.info(ret);
        routeDefinitionWriter.save(Mono.just(definition)).subscribe();
        this.publisher.publishEvent(new RefreshRoutesEvent(this));
        return ret;
    }

    private String deleteById(String id){
        try{
            this.routeDefinitionWriter.delete(Mono.just(id)).subscribe();
            log.info("网关删除路由：[{}]", id);
            this.publisher.publishEvent(new RefreshRoutesEvent(this));
            return "网关删除路由:" + id;
        }catch (Exception ex){
            String tip = "网关删除路由失败:" + ex.getMessage();
            log.error(tip);
            return tip;
        }
    }

    private String updateByRouteDefinition(RouteDefinition definition){
        try{
            this.routeDefinitionWriter.delete(Mono.just(definition.getId()));
            log.info("网关更新路由的第一步先删除：" + definition.getId());
        }catch(Exception ex){
            return "更新路由失败：" + definition.getId();
        }

        try {
            this.routeDefinitionWriter.save(Mono.just(definition)).subscribe();
            this.publisher.publishEvent(new RefreshRoutesEvent(this));
            return "网关更新路由：" + definition.getId();
        }catch (Exception ex){
            log.error("网关更新路由第二步新增时出现异常：" + definition.getId());
            return "更新路由失败：" + definition.getId();
        }
    }

    public String updateList(List<RouteDefinition> definitionList){
        log.info("网关批量更新路由：[{}]", definitionList);
        List<RouteDefinition> routeDefinitions = routeDefinitionLocator.getRouteDefinitions().buffer().blockFirst();

        // 先删除所有路由，之后在重新添加
        if(!CollectionUtils.isEmpty(routeDefinitions)){
            routeDefinitions.forEach(item -> {
                log.info("网关批量更新路由时删除一个路由：[{}]",item);
                deleteById(item.getId());
            });
        }

        // 逐个更新路由
        definitionList.forEach(item -> updateByRouteDefinition(item));
        return "批量更新路由成功";
    }
}
